【试题概览】
题目名称 |
数7 |
正方形计数 |
速算游戏 |
单人纸牌 |
提交文件 |
seven.* |
count.* |
fun.* |
double.* |
输入文件 |
seven.in |
count.in |
fun.in |
double.in |
输出文件 |
seven.out |
count.out |
fun.out |
double.out |
时间限制 |
1s |
1s |
1s |
1s |
空间限制 |
128MB |
128MB |
128MB |
128MB |
1. 数7
【题目描述】
1337 个人排成一个圈,从 1 号人开始报数,初始的方向是 1,2,3…。如果某个人报的数是 7 的倍数或 者数字中含有 7,那么报数的方向就反一下。问报数字 X 的是哪个人?
【输入格式】
一行一个数 X
【输出格式】
一行一个数表示最终报数字 X 的是哪个人。
【数据规模】
对于 30%的数据,满足 X<=10^6;
对于 90%的数据,满足 X<=10^8;
对于 100%的数据,满足 X<=10^9。
【输入样例】
1000
【输出样例】
1311
Solution
首先都想到了nlogn的做法,再想直接打表,如果打表的话估计也只能过10^8 ,而且还不稳定。先想想90分怎么做,考虑到主要的时间消耗在于对%7的判断以及对是否含有7的判断,与其取膜和分解判断,倒不如用个计数器和做类似于高精度加法(每次只加一复杂都有保证).然后对于10^9只能间隔打表了。
2.正方形计数
【题目描述】
给定平面上 N 个点,你需要计算以其中 4 个点为顶点的正方形的个数。注意这里的正方形边不一定 需要和坐标轴平行。
【输入格式】
第一行一个数 N 以下 N 个点的坐标。
【输出格式】
一个数,表示正方形的个数
【数据规模】
对于 20%的数据,满足 1<=N<=20;
对于 100%的数据,满足 1<=N<=500,-50<=x[i],y[i]<=50,点不会重叠。
【输入样例】
7
0 0
0 1
1 0
1 1
1 2
2 1
2 2
Solution
暴力枚举正方形的四个顶点判断边是否相等即可。或者枚举两个定点根据条件判断另外两个点是否存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; struct node{ int x,y; friend bool operator < (node a,node b){ if(a.x==b.x)return a.y<b.y; return a.x<b.x; } }point[550]; int n,ans; int work(int x1,int y1,int x2,int y2){ return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } int main() { freopen("count.in","r",stdin); freopen("count.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&point[i].x,&point[i].y); sort(point+1,point+1+n); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { int line_1=work(point[i].x,point[i].y,point[j].x,point[j].y); if(!line_1)continue; for(int k=j+1;k<=n;k++) { int line_2=work(point[i].x,point[i].y,point[k].x,point[k].y); if(line_1!=line_2)continue; for(int p=k+1;p<=n;p++) { int line_3=work(point[k].x,point[k].y,point[p].x,point[p].y); int line_4=work(point[p].x,point[p].y,point[j].x,point[j].y); int line_5=work(point[i].x,point[i].y,point[p].x,point[p].y); int line_6=work(point[j].x,point[j].y,point[k].x,point[k].y); if(line_2==line_3&&line_3==line_4&&line_5==line_6) ans++; } } } } printf("%d",ans); return 0; } 7 0 0 0 1 1 0 1 1 1 2 2 1 2 2 */
|
【输出样例】
3
3.速算游戏
【题目描述】
jyx 和 cyy 打赌,比谁 24 点算得快,算得慢的那个人请客。24 点的规则是这样的:给定 4
个 1..9 的整数,用括号改变运算顺序,通过加、减、乘、除通的一系列运算,得到整数 24,
注意所有中间结果必须是整数(例如(22)/4 是允许的,而 2(2/4)是不允许的)。为了赢得
这个比赛,请写一个程序帮助我作弊,快速地计算出 24 点。
【输入格式】
一行 4 个整数,为给定的 4 个数字。输入数据保证有解。
【输出格式】
一行,以字符串的形式输出结果,注意将每一步的运算的括号补齐(例如(3+5)+6 和
3*(5+6))如果有多种解答,输出字典顺序最小的一个。
【输入样例】
2357
【输出样例】
(((3*5)+2)+7)
Solution
被括号给骗了 感觉这道题挺蛮麻烦的,时只有3.5小时,所幸没有做,后来题时,真是傻逼题。太弱了…..括号在这题里只会有三种情况,自己想一想,然后依次写三个暴力就行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
| #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #define INF -2147483647 using namespace std; int n[5],now[10],vis[10],r[50]; int num[50][5]; int cnt,tot; char ans[50][100]; char trs(int x){ if(x==1)return '+'; if(x==2)return '-'; if(x==3)return '*'; if(x==4)return '/'; } void Dfs_Pai(int pos){ if(pos==5) { cnt++; for(int i=1;i<=4;i++) num[cnt][i]=now[i]; } for(int i=1;i<=4;i++) { if(!vis[i]) { now[pos]=n[i]; vis[i]=true; Dfs_Pai(pos+1); vis[i]=false; } } } int calu(int a,int b,int opt) { if(opt==1)return a+b; if(opt==2)return a-b; if(opt==3)return a*b; if(opt==4&&b!=0&&a%b==0)return a/b; return -INF; } void Dfs_Judge(int p) { for(int i=1;i<=4;i++) { int result_1=calu(num[p][1],num[p][2],i); if(result_1==-INF)continue; for(int j=1;j<=4;j++) { int result_2=calu(result_1,num[p][3],j); if(result_2==-INF)continue; for(int k=1;k<=4;k++) { int result=calu(result_2,num[p][4],k); if(result==24) { tot++; ans[tot][0]='('; ans[tot][1]='('; ans[tot][2]='('; ans[tot][3]=num[p][1]+'0'; ans[tot][4]=trs(i); ans[tot][5]=num[p][2]+'0'; ans[tot][6]=')'; ans[tot][7]=trs(j); ans[tot][8]=num[p][3]+'0'; ans[tot][9]=')'; ans[tot][10]=trs(k); ans[tot][11]=num[p][4]+'0'; ans[tot][12]=')'; } } } } for(int i=1;i<=4;i++) { int result_1=calu(num[p][1],num[p][2],i); if(result_1==-INF)continue; for(int j=1;j<=4;j++) { int result_2=calu(num[p][3],num[p][4],j); if(result_2==-INF)continue; for(int k=1;k<=4;k++) { int result=calu(result_1,result_2,k); if(result==24) { tot++; ans[tot][0]='('; ans[tot][1]='('; ans[tot][2]=num[p][1]+'0'; ans[tot][3]=trs(i); ans[tot][4]=num[p][2]+'0'; ans[tot][5]=')'; ans[tot][6]=trs(k); ans[tot][7]='('; ans[tot][8]=num[p][3]+'0'; ans[tot][9]=trs(j); ans[tot][10]=num[p][4]+'0'; ans[tot][11]=')'; ans[tot][12]=')'; } } } } for(int i=1;i<=4;i++) { int result_1=calu(num[p][3],num[p][4],i); if(result_1==-INF)continue; for(int j=1;j<=4;j++) { int result_2=calu(num[p][2],result_1,j); if(result_2==-INF)continue; for(int k=1;k<=4;k++) { int result=calu(num[p][1],result_2,k); if(result==24) { tot++; ans[tot][0]='('; ans[tot][1]=num[p][1]+'0'; ans[tot][2]=trs(k); ans[tot][3]='('; ans[tot][4]=num[p][2]+'0'; ans[tot][5]=trs(j); ans[tot][6]='('; ans[tot][7]=num[p][3]+'0'; ans[tot][8]=trs(i); ans[tot][9]=num[p][4]+'0'; ans[tot][10]=')'; ans[tot][11]=')'; ans[tot][12]=')'; } } } } } bool cmp(int x,int y){ for(int i=1;i<=13;i++) { if(ans[x][i]==ans[y][i])continue; return ans[x][i]<ans[y][i]; } } int main() { freopen("fun.in","r",stdin); freopen("fun.out","w",stdout); scanf("%d%d%d%d",&n[1],&n[2],&n[3],&n[4]); Dfs_Pai(1); for(int i=1;i<=cnt;i++) Dfs_Judge(i); for(int i=1;i<=tot;i++) r[i]=i; sort(r+1,r+1+tot,cmp); printf("%s",ans[r[1]]); return 0; } 2 3 5 7 */
|
4.单人纸牌
【题目描述】
单人纸牌游戏,共 36 张牌分成 9 叠,每叠 4 张牌面向上。每次,游戏者可以从某两个
不同的牌堆最顶上取出两张牌面相同的牌(如黑桃 10 和梅花 10)并且一起拿走。如果最
后所有纸牌都被取走,则游戏者就赢了,否则游戏者就输了。
George 很热衷于玩这个游戏,但是一旦有时有多种选择的方法,George 就不知道取
哪一种好了,George 会从中随机地选择一种走,例如:顶上的 9 张牌为 KS,KH,KD,9H,
8S,8D,7C,7D,6H,显然有 5 种取法: (KS,KH),(KS,KD),(KH,KD),(8S,
8D),(7C,7D),当然 George 取到每一种取法的概率都是 1/5。
有一次,George 的朋友 Andrew 告诉他,这样做是很愚蠢的,不过 George 不相信,
他认为如此玩最后成功的概率是非常大的。请写一个程序帮助 George 证明他的结论:计
算按照他的策略,最后胜利的概率。
【输入格式】
9 行每行 4 组用空格分开的字串,每个字串两个字符,分别表示牌面和花色,按照从堆
底到堆顶的顺序给出。
【输出格式】
一行,最后胜利的概率,精确到小数点后 6 位。
【输入样例】
AS 9S 6C KS
JC QH AC KH
7S QD JD KD
QS TS JS 9H
6D TD AD 8S
QC TH KC 8D
8C 9D TC 7C
9C 7H JH 7D
8H 6S AH 6H
【输出样例】
0.589314
Solution
记忆化搜索轻松搞定,其实比较裸吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> using namespace std; char ch[10][5]; bool f[5][5][5][5][5][5][5][5][5]; double dp[5][5][5][5][5][5][5][5][5]; double dfs(int c1,int c2,int c3,int c4,int c5,int c6,int c7,int c8,int c9) { if(f[c1][c2][c3][c4][c5][c6][c7][c8][c9]) return dp[c1][c2][c3][c4][c5][c6][c7][c8][c9]; f[c1][c2][c3][c4][c5][c6][c7][c8][c9]=true; int c[10]; c[1]=c1;c[2]=c2;c[3]=c3;c[4]=c4; c[5]=c5;c[6]=c6;c[7]=c7;c[8]=c8;c[9]=c9; int sum=0; for(int i=1;i<=9;i++) for(int j=i+1;j<=9;j++) { if(ch[i][c[i]]==ch[j][c[j]]&&(c[i]>0)&&(c[j]>0)) { sum++; c[i]--;c[j]--; dp[c1][c2][c3][c4][c5][c6][c7][c8][c9]+=dfs(c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9]); c[i]++;c[j]++; } } if(sum!=0) dp[c1][c2][c3][c4][c5][c6][c7][c8][c9]/=sum; return dp[c1][c2][c3][c4][c5][c6][c7][c8][c9]; } int main() { freopen("double.in","r",stdin); freopen("double.out","w",stdout); for(int i=1;i<=9;i++) for(int j=1;j<=4;j++) { char a,b; cin>>a>>b; ch[i][j]=a; } f[0][0][0][0][0][0][0][0][0]=1; dp[0][0][0][0][0][0][0][0][0]=1; dp[4][4][4][4][4][4][4][4][4]=dfs(4,4,4,4,4,4,4,4,4); printf("%.6f",dp[4][4][4][4][4][4][4][4][4]); return 0; } AS 9S 6C KS JC QH AC KH 7S QD JD KD QS TS JS 9H 6D TD AD 8S QC TH KC 8D 8C 9D TC 7C 9C 7H JH 7D 8H 6S AH 6H */
|